/*
 * test_client.c
 *
 *  Created on: 2022年1月6日
 *      Author: young
 */

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<signal.h>
#include<pthread.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<arpa/inet.h>

#define UNIX_SOCKET_PATH "cm_syllament"
#define UNIX_CLIENT_PATH "cm_client"

static int sock_fd;

static int startClient()
{
	struct sockaddr_un clt_unadr;
	int flag, ret;

	signal(SIGPIPE, SIG_IGN);
	unlink(UNIX_CLIENT_PATH);

	sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
	if(sock_fd < 0)
		return -1;

	flag = 1;
	setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));

	bzero(&clt_unadr, sizeof(struct sockaddr_un));
	clt_unadr.sun_family = AF_UNIX;
	strcpy(clt_unadr.sun_path, UNIX_CLIENT_PATH);

	ret = bind(sock_fd, (struct sockaddr *)&clt_unadr, sizeof(struct sockaddr));
	if(ret){
		close(sock_fd);
		return -1;
	}

	return sock_fd;
}

void *client_notify(void *arg)
{
	struct sockaddr_un unadr;
	char str[] = "hello";

	pthread_detach(pthread_self());

	bzero(&unadr, sizeof(unadr));
	unadr.sun_family = AF_LOCAL;
	strcpy(unadr.sun_path, UNIX_SOCKET_PATH);

	sendto(sock_fd, str, strlen(str), 0, (struct sockaddr *)&unadr, sizeof(struct sockaddr_un));

	while(1)
		sleep(1);

	return NULL;
}

void *client_mon(void *arg)
{
	pthread_t tid;
	int       ret;
	uint8_t   buf[255];

	pthread_detach(pthread_self());

	sock_fd = startClient();
	if(sock_fd < 0){
		printf("test_client start failed!\n");
		goto end;
	}

	pthread_create(&tid, NULL, client_notify, NULL);

	while(1){
		ret = recvfrom(sock_fd, buf, sizeof(buf), 0, 0, 0);
		if(ret > 0){
			buf[ret] = '\0';
			printf("client recv: %s\n", buf);
		}else
			break;
	}
end:
	return NULL;
}

void start_test_client()
{
	pthread_t tid;

	pthread_create(&tid, NULL, client_mon, NULL);
}
